﻿using System;
using System.Collections.Generic;
using System.Windows.Media;
using System.Linq;
using Bling.Core;
using Bling.DSL;
using Bling.WPF;
using Bling.WPF.Custom;
using Bling.Graphics;
using Bling.Angles;

namespace Bling.Example {
  using Bling.Matrices;
  using Bling.WPF3D;
  using Bling.DX;
  using Bling.Util;
  public class IntroGeom : HasDX10Canvas {
    public interface VSParticleIn : ISignature {
      [Semantics.Position()]
      Double3Bl Position { get; set; }
      [Semantics.Normal()]
      Double3Bl Velocity { get; set; }
      [Semantic("TIMER")]
      DoubleBl Timer { get; set; }
      VSParticleIn Bind { set; }
    }
    public interface Uniforms : ISignature {
      DoubleBl GlobalTime { get; set; }
    }

    public static readonly int MAX_COUNT = 100;
    public IntroGeom()
      : base(false) {
      // Set position of render host.
      Host.LeftTop = 0d;
      // The size of render host has to be constant.
      Host.Size = this.Bl().Size;

      // initialize buffers
      BaseBufferBl<VSParticleIn, Topology.PointKind> ParticleStart = new UserBuffer<VSParticleIn, Topology.PointKind, Topology.ListOrg>() {
        VertexCount = 1,
        F0 = (vid, input) => {
          input.Position = 0d;
          input.Velocity = new Double3Bl(0, 40, 0);
          input.Timer = -1d;
        },
      };
      var ParticleA = new StreamOutBuffer<VSParticleIn, Topology.PointKind>() { MaxCount = MAX_COUNT, };
      var ParticleB = new StreamOutBuffer<VSParticleIn, Topology.PointKind>() { MaxCount = MAX_COUNT, };

      var Effect = new Effect<Uniforms>();

      var PassThroughVS = new Effect<Uniforms>.VertexShader<VSParticleIn, VSParticleIn>(Effect, (uniforms, input, output, vertex) => {
        output.Bind = input;
      });
      var UpdateGS = new Effect<Uniforms>.GeometryShader<VSParticleIn, VSParticleIn, Topology.PointKind, Topology.PointKind>(Effect, (uniforms, inputs, geom) => {
        var input = inputs(0); // just a point, so only one vertex per instance. 
        return new Effect.GeometryStream<VSParticleIn, Topology.PointKind>().Build((streamA) => {
          var IsNew = input.Timer < 0d;
        });
      });
    }
  }
}
